﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace System.Linq
{
    public static class ReflectionHelper
    {
        public static T[] GetImplementObjects<T>()
        {
            var type = typeof(T);
            if (type.Assembly == null)
                throw new ArgumentNullException(nameof(type.Assembly));

            var typesList = type.Assembly.GetExportedTypes().Where(a =>
            {
                if (!a.IsClass || a.IsAbstract)
                    return false;

                if (type.IsInterface)
                    return a.GetInterfaces().Contains(type);

                return type.IsClass && a.IsSubclassOf(type);
            }).ToList();

            var list = new List<T>();
            typesList.ForEach(a => list.Add((T)a.GetConstructor(Array.Empty<Type>())!.Invoke(null)));

            return list.ToArray();
        }
    }
}